package com.stefanini.pe.bbva.bp.in.bo.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.MethodExpressionActionListener;
import javax.faces.model.SelectItem;

import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.component.submenu.Submenu;
import org.primefaces.model.DefaultMenuModel;
import org.primefaces.model.MenuModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.pe.bbva.utils.Constantes;
import com.stefanini.pe.bbva.bp.in.bo.iface.OpcionesMenuBOIface;
import com.stefanini.pe.bbva.bp.in.dao.iface.OpcionesMenuDAOIface;
import com.stefanini.pe.bbva.bp.in.to.UsuarioAsesor;
import com.stefanini.pe.bbva.bp.in.to.UsuarioSesion;
import com.stefanini.pe.bbva.bp.in.utils.Util;

@Service("opcionesMenuBO")
public class OpcionesMenuBOImpl implements OpcionesMenuBOIface{
	
	@Autowired
	public OpcionesMenuDAOIface opcionesMenuDAOIface;

	private Integer countIndex;
	
	public List listarMenu(String codRegistro, int idPerfil) throws Exception{
		return opcionesMenuDAOIface.listarMenu(codRegistro, idPerfil);
	}
	
	public MenuModel crearArbolMenuOpcion(List list, String tipoOpcion)
		throws Exception {
		MenuModel root = new DefaultMenuModel();
		if (list != null) {
			if (list.size() > 0) {
				int count=0;
				countIndex = 0;
				for(Iterator it = list.iterator(); it.hasNext();) {
					count++;
					HashMap menu = (HashMap)it.next();
					MenuItem menuItem = null;
					Submenu submenu = null;
					if (menu.get("IDOPCIONPADRE") == null) {
						if(Util.isString(menu.get("CODTIPOOPCION")).equals(tipoOpcion) && 
								Util.isString(menu.get("INDPERMISO")).equals("S")){
							if(isUltimoHijo(list, menu)){
								menuItem = createMenuItem(menu, String.valueOf(count), tipoOpcion);
							}else{
								submenu = new Submenu();
								submenu.setLabel(Util.isString(menu.get("NOMOPCION")).trim());
								addMenuItemToSubMenu(menu, list, submenu, count, tipoOpcion);
							}
						}
					} else {
						break;
					}
					if(menuItem != null){
						root.addMenuItem(menuItem);
					}else if(submenu != null){
						root.addSubmenu(submenu);
					}
				}
			}
		}
		return root;
	}
		
	private void addMenuItemToSubMenu(HashMap menu, List list, Submenu submenu, int index, String tipoOpcion)
		throws Exception {
		int count=0;
		for(Iterator it = list.iterator(); it.hasNext();) {
			count++;
			HashMap drMenuResumen = (HashMap)it.next();
			if(Util.isString(menu.get("IDOPCION")).equals(Util.isString(drMenuResumen.get("IDOPCIONPADRE")))){
				if(Util.isString(menu.get("CODTIPOOPCION")).equals(tipoOpcion) &&
						Util.isString(menu.get("INDPERMISO")).equals("S")){
					if(isUltimoHijo(list, drMenuResumen)){
						MenuItem menuItem = createMenuItem(drMenuResumen, String.valueOf(index)+String.valueOf(count), tipoOpcion);
						submenu.getChildren().add(menuItem);
					}else{
						Submenu drSubmenu = new Submenu();
						drSubmenu.setLabel(Util.isString(drMenuResumen.get("NOMOPCION")).trim());
						submenu.getChildren().add(drSubmenu);
						addMenuItemToSubMenu(drMenuResumen, list, drSubmenu, index, tipoOpcion);
					}
				}
			}
		}
	}
	
	private boolean isUltimoHijo(List list, HashMap menu){
		boolean ultimoHijo = true;
		for(Iterator it = list.iterator(); it.hasNext();) {
			HashMap ob = (HashMap)it.next();
			if(Util.isString(menu.get("IDOPCION")).equals(Util.isString(ob.get("IDOPCIONPADRE")))){
				ultimoHijo = false;
				break;
			}
		}
		return ultimoHijo;
	}
	
	private MenuItem createMenuItem(HashMap menu, String id, String tipoOpcion){
		MenuItem item = new MenuItem();
		
		item.setValue(Util.isString(menu.get("NOMOPCION")).trim());
		String url = Util.isString(menu.get("URL"));
		if(url != null && url.trim().length() > 0){
			url = url.trim();
		}else{
			url = Constantes.SIMBOLO_NUMERAL;
		}
		
		if("2".equals(tipoOpcion) || "3".equals(tipoOpcion)){
			item.getAttributes().put("idobjectURL",url);
			item.getAttributes().put("idobjectIndex",countIndex);
			
			ExpressionFactory factory = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
	        ELContext elContext = FacesContext.getCurrentInstance().getELContext();
	        if("2".equals(tipoOpcion)) {
		        MethodExpression expression = factory.createMethodExpression(elContext, "#{clienteController.changeIndexMenuCliente}", 
		        		Void.TYPE, new Class[] {ActionEvent.class});
		        item.addActionListener(new MethodExpressionActionListener(expression));
	        }
	        if("3".equals(tipoOpcion)) {
		        MethodExpression expression = factory.createMethodExpression(elContext, "#{noClienteController.changeIndexMenuNoCliente}", 
		        		Void.TYPE, new Class[] {ActionEvent.class});
		        item.addActionListener(new MethodExpressionActionListener(expression));
	        }
	        countIndex++;
		}else{
			item.setUrl(url);
		}
		
		item.setId("id_menuOpcion_"+id+tipoOpcion);
		
		return item;
	}
	
	public List listarTipoEjecutivo(String codRegistro) throws Exception{
		 List list=opcionesMenuDAOIface.listarTipoEjecutivo(codRegistro);
		 List listTiposEjecutivos=new ArrayList();
		 for (Iterator iter = list.iterator(); iter.hasNext();) {
			 	HashMap element = (HashMap) iter.next();
				listTiposEjecutivos.add(new SelectItem(Util.getStringF(element.get("IDTIPOEJECUTIVO")),
								Util.getStringF(element.get("DESCRIPCION"))));
			}
		 return listTiposEjecutivos;
	}
	
	public List listarTipoEjecutivo(String codRegistro, UsuarioSesion oUsuarioSesion) throws Exception{
		List list=opcionesMenuDAOIface.listarTipoEjecutivo(codRegistro, oUsuarioSesion);
		 List listTiposEjecutivos=new ArrayList();
		 for (Iterator iter = list.iterator(); iter.hasNext();) {
			 	HashMap element = (HashMap) iter.next();
				listTiposEjecutivos.add(new SelectItem(Util.getStringF(element.get("IDTIPOEJECUTIVO")),
								Util.getStringF(element.get("DESCRIPCION"))));
			}
		 return listTiposEjecutivos;
	}
	
	public List listarJerarquia(int idUsuarioAsesor) throws Exception{
		return opcionesMenuDAOIface.listarJerarquia(idUsuarioAsesor);
	}
	
	public UsuarioAsesor listarTipoEjecutivoById(Long idUsuarioAsesor) throws Exception{
		return opcionesMenuDAOIface.listarTipoEjecutivoById(idUsuarioAsesor);
	}
}